package com.iot08.admin.service;

import com.iot08.admin.service.page.PageVO;
import com.iot08.admin.service.page.PageableImpl;
import com.iot08.common.constant.Const;
import com.iot08.common.entity.admin.Operation;
import com.iot08.common.entity.admin.SysUser;
import com.iot08.common.response.Response;
import com.iot08.common.utils.DateUtil;
import com.iot08.common.utils.StringUtil;
import com.iot08.common.utils.UUIDGenerator;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.File;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

/**
 * @version 1.0
 * @Description:
 * @time: 2020/8/28 14:09
 * @author: Rock
 */
@Service
public class OperationService {

    @Resource(name = "adminMongoTemplate")
    private MongoTemplate mongoTemplate;
    @Resource
    private UserService userService;

    @Value("${device.import.path: }")
    private String importPath;

    /**
     * 添加操作记录
     *
     * @param [account, ip, type, module, company, behavior, describe, vender, filename]
     * @time: 2020/8/28 14:38
     * @author: Rock
     * @version 1.0
     */
    public void add(SysUser user, String ip, String type, String module, String company,
                    String behavior, String describe, Integer vender, String filename, String imei) {
        Operation o = new Operation();
        o.setId(UUIDGenerator.generate());
        o.setAccount(user.getAccount());
        o.setRole(user.getRole().getName());
        if (StringUtils.isNotEmpty(ip)) {
            o.setIp(ip);
        }
        if (StringUtils.isEmpty(type)) {
            o.setT("common");
        } else {
            o.setT(type);
        }
        if (StringUtils.isNotEmpty(module)) {
            o.setModule(module);
        }
        if (StringUtils.isEmpty(company)) {
            o.setCompany("总部");
        } else {
            o.setCompany(company);
        }
        if (StringUtils.isNotEmpty(behavior)) {
            o.setBehavior(behavior);
        }
        if (StringUtils.isNotEmpty(describe)) {
            o.setDescribe(describe);
        }
        if (vender == null) {
            o.setVender(Const.VENDER_8888);
        } else {
            o.setVender(vender);
        }
        if (StringUtils.isNotEmpty(filename)) {
            o.setFilename(filename);
        }
        if (StringUtils.isNotEmpty(imei)) {
            o.setImei(imei);
        }
        o.setMaketime(new Date());
        mongoTemplate.save(o);
    }

    /**
     * @param user
     * @param ip
     * @param module
     * @param behavior
     * @param describe
     * @time: 2020/11/25 18:13
     * @author: Rock
     * @version 1.0
     */
    public void add(SysUser user, String ip, String module, String behavior, String describe) {
        add(user, ip, null, module, null, behavior,
                describe, null, null, null);
    }

    /**
     * @param user
     * @param ip
     * @param module
     * @param behavior
     * @param describe
     * @param filename
     * @time: 2020/12/31 18:31
     * @author: Rock
     * @version 1.0
     */
    public void add(SysUser user, String ip, String module, String behavior, String describe, String filename) {
        add(user, ip, null, module, null, behavior,
                describe, null, filename, null);
    }

    /**
     * @param [page, type, role, ip, startTime, endTime, user]
     * @time: 2020/9/14 16:06
     * @author: Rock
     * @version 1.0
     */
    public Page<Operation> list(PageVO page, int type, String role, String ip, String startTime,
                                String endTime, SysUser user) {
        PageableImpl pageable = new PageableImpl();
        page.setSort(Sort.by(Sort.Order.desc("maketime")));
        pageable.setPage(page);

        Criteria criteria = new Criteria();
        if (StringUtils.isNotEmpty(page.getSearchValue())) {
            criteria.and("account").regex(".*?" + page.getSearchValue() + ".*?", "i");
        }
        if (type == 1) {
            criteria.and("T").is(Const.OPERATION_DELETE);
        } else if (type == 2) {
            criteria.and("T").is(Const.OPERATION_ADD);
        } else if (type == 3) {
            criteria.and("T").is(Const.OPERATION_REMOVE);
        } else if (type == 4) {
            criteria.andOperator(Criteria.where("T").ne(Const.OPERATION_DELETE),
                    Criteria.where("T").ne(Const.OPERATION_ADD), Criteria.where("T").ne(Const.OPERATION_REMOVE));
        }
        if (StringUtils.isNotEmpty(role)) {
            criteria.and("role").regex(".*?" + role + ".*?", "i");
        }
        if (StringUtils.isNotEmpty(ip)) {
            criteria.and("ip").regex(".*?" + ip + ".*?", "i");
        }
        if (user.getType() == Const.CHANNELUSER_TYPE) {
            criteria.and("account").is(user.getAccount());
        }
        if (StringUtils.isNotEmpty(startTime) && StringUtils.isNotEmpty(endTime)) {
            criteria.and("maketime").gte(DateUtil.strToDate(startTime)).lte(DateUtil.strToDate(endTime));
        } else if (StringUtils.isNotEmpty(startTime)) {
            criteria.and("maketime").gt(DateUtil.strToDate(startTime));
        } else if (StringUtils.isNotEmpty(endTime)) {
            criteria.and("maketime").lt(DateUtil.strToDate(endTime));
        }

        Query query = new Query().addCriteria(criteria);
        long count = mongoTemplate.count(query, Operation.class);
        page.setTotalResult((int) count);
        List<Operation> list = mongoTemplate.find(query.with(pageable), Operation.class);
        for (Operation operation : list) {
            if (StringUtil.isNotBlank(operation.getAccount())) {
                operation.setUser(userService.getByAccount(operation.getAccount()));
            }
        }
        Page<Operation> result = new PageImpl<Operation>(list, pageable, count);
        return result;
    }

    /**
     * @param [type, user, ids, ip]
     * @time: 2020/9/14 15:18
     * @author: Rock
     * @version 1.0
     */
    public Response<Object> del(int type, SysUser user, String ids, String ip) {
        if (StringUtils.isNotEmpty(ids)) {
            String[] idArr = ids.split(",");
            Query query = new Query(Criteria.where("_id").in(Arrays.asList(idArr)));
            query.fields().include("_id").include("filename");
            //先删除文件
            List<Operation> list = mongoTemplate.find(query, Operation.class);
            for (Operation op : list) {
                if (op != null && StringUtils.isNotEmpty(op.getFilename())) {
                    File file = new File(importPath + File.separator + op.getFilename());
                    if (file != null && file.exists() && file.isFile()) {
                        file.delete();
                    }
                }
            }
            //再删除记录
            mongoTemplate.remove(query, Operation.class);
            if (type == 1) {
                add(user, ip, null, "设备解绑日志", null, "删除", "删除解绑操作日志", null, null, null);
            } else if (type == 2) {
                add(user, ip, null, "设备录入日志", null, "删除", "删除设备录入操作日志", null, null, null);
            } else if (type == 3) {
                add(user, ip, null, "设备删除日志", null, "删除", "删除设备删除操作日志", null, null, null);
            }
            return Response.successResponse(idArr.length);
        }
        return Response.failedResponse();
    }
}
